/*
* @Author: gaara  
* @Date: 2020-06-13 11:55:34  
*/
import _path from 'path'
import _fs from 'fs-extra'
import _plist from 'plist'

import { RawAsset } from "./RawAsset";
import { SpriteFrame } from './SpriteFrame';
import { fstat } from 'fs';
import { UuidMgr } from '../UuidMgr';

/**
 * 图片文件
 */
export class Size {
    width: number = 0;
    height: number = 0;
}

export class Plist extends RawAsset {

    rawTextureUuid: string;

    size: Size;

    type: string;

    constructor(path: string) {
        super(path);

        this.rawTextureUuid = "";

        this.size = new Size();

        this.type = "Texture Packer";
    }

    static version() {
        return '1.2.4';
    }

    static defaultType(): string[] {
        return [".plist"];
    }

    /**
     * 解析pilst的参数
     * @param str 
     */
    parseParams(str: string): number[] {
        let paramsStr: string[] = [];
        try {
            paramsStr = str.replace(/{/g, '').replace(/}/g, '').split(',');
        } catch (error) {
            console.error("错误图集", this.__path__);
        }

        let params: number[] = [];
        for (const sub of paramsStr) {
            params.push(+sub);
        }
        return params;
    }

    /**
     * 是否存在meta
     */
    check() {
        let str = _fs.readFileSync(this.__path__, { encoding: "utf8" });
        let plistObj = _plist.parse(str) as any;
        var frames = plistObj.frames;
        let metadata = plistObj.metadata;

        let sizeStr: string = metadata.size;
        let pSize = this.parseParams(sizeStr);

        let isChange: boolean = false;
        let metaPath = this.getMetaPath();
        let json = _fs.readJSONSync(metaPath);

        //检查帧数
        let metalen = Object.keys(json.subMetas).length;
        let framelen = Object.keys(frames).length;
        if (metalen != framelen) {
            isChange = true;
        }

        //检查尺寸
        if (!isChange) {
            let metaSise = json.size;
            if (metaSise.width != pSize[0] || metaSise.height != pSize[1]) {

                isChange = true;
            }
        }

        //检查每帧
        if (!isChange) {
            let subMetas = json.subMetas;
            for (const key in subMetas) {
                let sub = subMetas[key];
                let subPlist = frames[key] as any;

                let textureRectStr: string = subPlist.textureRect;
                let rect = this.parseParams(textureRectStr);

                if (sub.trimX != rect[0] || sub.trimY != rect[1] || sub.width != rect[2] || sub.height != rect[3]) {
                    isChange = true;
                    break;
                }
            }
        }

        if (isChange) {
            _fs.removeSync(metaPath);
            return false;
        }

        return true;
    }

    importPath() {
        let pngPath = this.__path__.replace(".plist", '.png');
        let pngUUid = UuidMgr.getUUID(pngPath)
        this.rawTextureUuid = pngUUid

        let str = _fs.readFileSync(this.__path__, { encoding: "utf8" });
        let plistObj = _plist.parse(str) as any;
        var frames = plistObj.frames;
        for (const key in frames) {
            if (frames.hasOwnProperty(key)) {
                const element = frames[key];
                let subp = _path.join(this.__path__, key);
                let sf = this.__subMetas__[key] = new SpriteFrame(subp);

                sf.rawTextureUuid = pngUUid;
                // sf.trimThreshold = 1;

                sf.rotated = element.textureRotated;

                //offset
                let spriteOffsetStr: string = element.spriteOffset;
                let spriteOffset = this.parseParams(spriteOffsetStr);
                sf.offsetX = spriteOffset[0];
                sf.offsetY = spriteOffset[1];

                let textureRectStr: string = element.textureRect;
                let rect = this.parseParams(textureRectStr);

                sf.trimX = rect[0];
                sf.trimY = rect[1];

                sf.width = rect[2];
                sf.height = rect[3];

                let spriteSourceSize: string = element.spriteSourceSize;
                let sourceSize = this.parseParams(spriteSourceSize);
                sf.rawWidth = sourceSize[0];
                sf.rawHeight = sourceSize[1];

                sf.spriteType = "normal";
            }
        }

        let metadata = plistObj.metadata;

        let sizeStr: string = metadata.size;
        let size = this.parseParams(sizeStr);
        this.size.width = size[0];
        this.size.height = size[1];
    }
}